package com.dingreading.cloud.web.controller;

import com.alibaba.fastjson.JSONObject;
import com.dingreading.cloud.common.util.wechat.AuthToken;
import com.dingreading.cloud.common.util.wechat.PayConfig;
import com.dingreading.cloud.common.util.wechat.WxDataUtils;
import com.dingreading.cloud.common.util.wechat.WxPayBusiness;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.ServletInputStream;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Map;
import java.util.Objects;

@RestController
@RequestMapping("/wx/web")
@Api(tags = "微信-公众号开发")
public class WxGzhController {

    // 叮叮文化
    @Value("${wx.appId}")
    private String appId;
    @Value("${wx.appSecret}")
    private String appSecret;
    // 叮叮书房
    @Value("${wx.sf.appId}")
    private String shAppId;
    @Value("${wx.sf.appSecret}")
    private String shAppSecret;

    @ApiOperation(value = "接收微信推送事件")
    @RequestMapping(value = "/receiveMessage", produces = "application/json; charset=UTF-8")
    public void receiveMessage(HttpServletRequest request, HttpServletResponse response) throws Exception {
        try {
            System.out.println("微信推送事件");
            ServletInputStream inputStream = request.getInputStream();
            ServletOutputStream outputStream = response.getOutputStream();
            String signature = request.getParameter("signature");
            String timestamp = request.getParameter("timestamp");
            String nonce = request.getParameter("nonce");
            String echostr = request.getParameter("echostr");

            //首次请求申请验证,返回echostr
            if (echostr != null) {
                outputStreamWrite(outputStream, echostr);
                return;
            }
            //验证请求签名
            if (!signature.equals(generateEventMessageSignature(PayConfig.TOKEN, timestamp, nonce))) {
                System.out.println("推送消息的 signature is invalid");
                return;
            }
            if (Objects.nonNull(inputStream)) {
                Map<String, String> wxData = WxDataUtils.parseXml(inputStream);
                System.out.println("微信推送事件接收：\n" + wxData);
                //接受到的消息中：tousername=开发者公众号，fromusername=openid
                String FromUserName = wxData.get("FromUserName");
                String ToUserName = wxData.get("ToUserName");
                String CreateTime = wxData.get("CreateTime");
                String MsgType = wxData.get("MsgType");
                String Content = wxData.get("Content");
                // 事件类型
                String eventType = wxData.get("Event");

                //转换XML
                if (wxData.get("MsgType") != null) {
                    if ("event".equals(wxData.get("MsgType"))) {
//                        System.out.println("解析消息内容为：事件推送");
                        if ("subscribe".equals(eventType)) {
                            System.out.println("关注");
                            //关注回复
//                            WxGzhUserUtil.saveWxGzhUser(FromUserName);
                        } else if ("unsubscribe".equals(eventType)) {
                            //取消关注
                            System.out.println("取消订阅)");
                        } else if ("SCAN".equals(eventType)) {
                            //扫码
                            System.out.println("用户扫码");
                        } else if ("LOCATION".equals(eventType)) {
                            //上报地理位置事件
                            System.out.println("上报地理位置事件");
                        } else if ("CLICK".equals(eventType)) {
                            System.out.println("点击菜单拉取消息时的事件推送");
                            //点击菜单拉取消息时的事件推送,EventKey是key
                            String EventKey = wxData.get("EventKey");
                            if (EventKey.equals("grow")) {
                                //成长
                            }
                        } else if ("VIEW".equals(eventType)) {
                            //点击菜单跳转链接时的事件推送,EventKey是key是url
                            String EventKey = wxData.get("EventKey");
                            System.out.println("点击菜单跳转链接时的事件推送");
                        } else if ("TEMPLATESENDJOBFINISH".equals(eventType)) {
                            //模版消息发送任务完成后的事件推送
                            System.out.println("模版消息发送任务完成后的事件推送");
                        }
                    } else if ("text".equals(wxData.get("MsgType"))) {
                        //文本消息
                        System.out.println("解析消息内容为：文本消息");
                        //回复
//                        String text = WxMessageUtils.XmlTextMessage(FromUserName, ToUserName, Content);
//                        outputStreamWrite(outputStream, text);
                    } else if ("image".equals(wxData.get("MsgType"))) {
                        //图片消息
                        System.out.println("解析消息内容为：图片消息");
                    } else if ("voice".equals(wxData.get("MsgType"))) {
                        //语音消息
                        System.out.println("解析消息内容为：语音消息");
                    } else if ("video".equals(wxData.get("MsgType"))) {
                        //视频消息
                        System.out.println("解析消息内容为：视频消息");
                    } else if ("shortvideo".equals(wxData.get("MsgType"))) {
                        //小视频消息
                        System.out.println("解析消息内容为：小视频消息");
                    } else if ("location".equals(wxData.get("MsgType"))) {
                        //地理位置消息
                        System.out.println("解析消息内容为：地理位置消息");
                    } else if ("link".equals(wxData.get("MsgType"))) {
                        //链接消息
                        System.out.println("解析消息内容为：链接消息");
                    }
                }

            }
        } catch (Exception e) {
            throw e;
        }
        return;
    }

    @ApiOperation(value = "微信获取openid接口(合肥叮叮文化科技有限公司)")
    @PostMapping(value = "/getOpenId", produces = "application/json; charset=UTF-8")
    public String getOpenId(
            @RequestParam(value = "code") @ApiParam(value = "微信授权码") String code
    ) throws Exception {
        JSONObject resultObj = new JSONObject();
        try {
            AuthToken authToken = WxPayBusiness.Init().getAccessToken(code, appId, appSecret);
            if (authToken != null) {
                resultObj.put("data", authToken.getOpenid());
                resultObj.put("status", 500);
                resultObj.put("message", "操作成功");
            }
        } catch (Exception e) {
            throw e;
        }
        return resultObj.toString();
    }

    @ApiOperation(value = "微信获取openid接口(合肥叮叮书房文化科技有限公司)")
    @PostMapping(value = "/getSfOpenId", produces = "application/json; charset=UTF-8")
    public String getSfOpenId(
            @RequestParam(value = "code") @ApiParam(value = "微信授权码") String code
    ) throws Exception {
        JSONObject resultObj = new JSONObject();
        try {
            AuthToken authToken = WxPayBusiness.Init().getAccessToken(code, shAppId, shAppSecret);
            if (authToken != null) {
                resultObj.put("data", authToken.getOpenid());
                resultObj.put("status", 500);
                resultObj.put("message", "操作成功");
            }
        } catch (Exception e) {
            throw e;
        }
        return resultObj.toString();
    }


    /**
     * 数据流输出
     *
     * @param outputStream
     * @param text
     * @return
     */
    private boolean outputStreamWrite(OutputStream outputStream, String text) {
        try {
            outputStream.write(text.getBytes(StandardCharsets.UTF_8));
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return false;
        }
        return true;
    }

    /**
     * 生成事件消息接收签名
     *
     * @param token     token
     * @param timestamp timestamp
     * @param nonce     nonce
     * @return str
     */
    public static String generateEventMessageSignature(String token, String timestamp, String nonce) {
        String[] arr = new String[]{token, timestamp, nonce};
        Arrays.sort(arr);
        if (arr == null || arr.length == 0) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < arr.length; i++) {
            if (i > 0) {
            }
            sb.append(arr[i]);
        }
        String s = sb.toString();
        return DigestUtils.shaHex(s);
    }

}
